<template>
  <div>
    <div id="map" ref="mapContainer" class="chart-map" />
    <div class="select-box">
      <el-select v-model="selectedSite" value-key="siteId" class="select" size="medium" placeholder="请选择区站" @change="gotoSiteLocation">
        <el-option
          v-for="item in siteList"
          :key="item.siteId"
          :label="item.siteName"
          :value="item" />
      </el-select>
      <el-select v-model="selectedDevice" value-key="deviceId" class="select" size="medium" placeholder="请选择设备" @change="gotoDeviceLocation">
        <el-option
          v-for="item in deviceInfoList"
          :key="item.deviceId"
          :label="item.deviceName"
          :value="item" />
      </el-select>
      <el-checkbox-group v-model="checkList" class="checkBox" @change="showOption">
        <el-checkbox label="区站" />
        <el-checkbox label="设备" />
      </el-checkbox-group>
    </div>
    <div class="map-location">
      <img class="image" src="@/assets/map_icon/map_location.png" @click="backMapCenter">
    </div>
    <div class="map-full-screen">
      <img class="image" src="@/assets/map_icon/fullscreen.png" @click="toggleFullScreen">
    </div>
    <div class="map-zoom">
      <img class="image zoom-in" src="@/assets/map_icon/zoom-in.png" @click="zoomIn">
      <div class="line" />
      <img class="image zoom-out" src="@/assets/map_icon/zoom-out.png" @click="zoomOut">
    </div>
    <div v-show="showPopup" ref="activeIcon" class="active-icon">
      <div v-if="showPopup && popupType==='device'" class="device-icon-box">
        <img src="@/assets/map_icon/device.png" class="icon">
        <div class="ripple-icon" />
      </div>
      <div v-if="showPopup && popupType==='site'" class="site-icon-box">
        <img src="@/assets/map_icon/site.png" class="icon">
        <div class="ripple-icon" />
      </div>
    </div>
    <div v-show="showPopup" ref="popup" class="popup">
      <div class="header-box" :class="{'site-header':popupType==='site', 'device-header':popupType==='device'}">
        <img v-if="showPopup && popupType==='device' && selectedDevice.connectStatus === 'ONLINE'" class="network" src="@/assets/images/online3.png">
        <img v-if="showPopup && popupType==='device' && selectedDevice.connectStatus !== 'ONLINE'" class="network" src="@/assets/images/offline3.png">
        <div v-if="popupType==='site'" class="title">区站信息</div>
        <div v-if="popupType==='device'" class="title">设备信息</div>
        <img src="@/assets/images/close.png" class="close" @click="closePopup">
      </div>
      <div v-if="showPopup && popupType==='site'" class="content-box">
        <div class="text item">{{ '区站名称: ' + this.selectedSite.siteName }}</div>
        <div class="text item">{{ '经度: ' + this.selectedSite.longitude }}</div>
        <div class="text item">{{ '纬度: ' + this.selectedSite.latitude }}</div>
      </div>
      <div v-if="showPopup && popupType==='device'" class="content-box">
        <div class="text item">{{ '设备名称: ' + this.selectedDevice.deviceName }}</div>
        <div class="text item">{{ '经度: ' + this.selectedDevice.longitude }}</div>
        <div class="text item">{{ '纬度: ' + this.selectedDevice.latitude }}</div>
        <el-button class="btn" size="mini" @click="gotoIntimeData">设备实时数据</el-button>
      </div>
    </div>
  </div>
</template>

<script>
import { Map, View, Feature, Overlay } from 'ol'
import * as olProj from 'ol/proj'
import { Style, Fill, Stroke, Circle, Icon, Text } from 'ol/style'
import { Point } from 'ol/geom'
import { Tile as TileLayer } from 'ol/layer'
import XYZ from 'ol/source/XYZ'
import { Vector as VectorLayer } from 'ol/layer'
import { Vector as VectorSource } from 'ol/source'
import { getAllDeviceInfo } from '@/api/cms/winglinks/device'
import { siteList } from './site'
export default {
  name: 'Index',
  data() {
    return {
      siteList: siteList,
      // 地图对象
      mapObject: null,
      // 地图最大zoom
      maxZoom: 12,
      // 地图最小zoom
      minZoom: 3,
      // 默认zoom
      defaultZoom: 8,
      // 默认中心
      defaultCenter: [114.64, 38.32],
      centerLocation: {
        longitude: null,
        latitude: null
      },
      // 设备信息
      deviceInfoList: [],
      // 选择的device
      selectedDevice: undefined,
      // 选择的site
      selectedSite: undefined,
      // 设置中心点的layer
      centerLayer: null,
      // 选择的设备layer
      selectedDeviceLayer: null,
      // 选择的区站layer
      selectedSiteLayer: null,
      // 区站layer
      siteLayer: null,
      // 设备layer
      deviceLayer: null,
      // 选择的设备Overlay
      selectedDeviceOverlay: null,
      // 选择的区站Overlay
      selectedSiteOverlay: null,
      activeIcon: null,
      // popup
      popup: null,
      // showPopup
      showPopup: false,
      // 弹窗类型
      popupType: undefined,
      // 弹窗内容
      popupContent: undefined,
      // checkList
      checkList: ['区站', '设备']
    }
  },
  mounted() {
    this.initMap()
    this.addSiteMarker()
    this.singleClick(false)
    this.addOverlay()
    this.addActiveIconOverlay()
    this.getAllDeviceInfo()
  },
  methods: {
    /**
     * 初始化地图
     */
    initMap() {
      this.mapObject = new Map({
        target: 'map',
        layers: [
          new TileLayer({
            source: new XYZ({
              // 星图瓦片地址
              url: 'https://tiles3.geovisearth.com/base/v1/vec/{z}/{x}/{y}?format=webp&token=e8933b32700e5c2b00f5eb2fa42628842af7a60a2c6142d1d65f1f8ed592ce12'
              // url: 'https://wprd0{1-4}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&style=7&x={x}&y={y}&z={z}'
              // url: process.env.VUE_APP_MAP_DIRECTION
              // url: 'http://10.48.37.32:8080/OneMapServer/rest/services/BaseMap_cache/MapServer/WMTS?service=WMTS&version=1.0.0&request=GetTile&format=image%2Fpng&layer=BaseMap_cache&style=default&tilematrixset=default028mm&tilecol={x}&tilerow={y}&tilematrix={z}&token=null'
            })
          })
        ],
        view: new View({
          // 中心
          center: olProj.fromLonLat(this.defaultCenter),
          // zoom
          zoom: this.defaultZoom,
          // maxZoom
          maxZoom: this.maxZoom,
          // minZoom
          minZoom: this.minZoom,
          // EPSG: 3857 --web地图，基于球体的、web墨卡托投影（伪墨卡托投影Pseudo-Mercator）的投影坐标系，范围为纬度85度以下，由于google地图最先使用而成为事实标准。至今，大多互联网地图都使用EPSG3857，主要是因为该投影是等角投影，适合地图定向及导航，但是纬度越高，面积变形越大。
          // EPSG: 4326 --全球通用，基于WGS84椭球的经纬度坐标系，大地坐标系
          // 投影
          projection: 'EPSG:3857'
        }),
        controls: []
      })
    },

    /**
     * 地图点击时间
     * @param isDot 是否做打点
     */
    singleClick(isDot) {
      this.mapObject.on('singleclick', (evt) => {
        console.log(evt)
        // 判断是否点击在点上，如果是点（feature为undefined），弹窗，不是打点
        const feature = this.mapObject.forEachFeatureAtPixel(
          evt.pixel,
          (feature) => feature
        )
        this.showPopup = false
        if (feature) {
          const coordinates = feature.getGeometry().getCoordinates()
          if (feature.getId().startsWith('device')) {
            // this.addSelectedDeviceMarker(coordinates)
            this.popupType = 'device'
            const deviceId = feature.getId().replace('device-', '')
            this.selectedDevice = this.deviceInfoList.find((item) => item.deviceId === deviceId)
          } else if (feature.getId().startsWith('site')) {
            // this.addSelectedSiteMarker(coordinates)
            this.popupType = 'site'
            const siteId = feature.getId().replace('site-', '')
            this.selectedSite = this.siteList.find((item) => item.siteId === siteId)
          }
          this.showPopup = true
          this.setMapCenter(coordinates)
          // 设置弹窗位置
          this.popup.setPosition(coordinates)
          this.activeIcon.setPosition(coordinates)
        } else if (isDot) {
          // 坐标轴转为经纬度
          const coordinate = olProj.transform(evt.coordinate, 'EPSG:3857', 'EPSG:4326')
          console.log(coordinate)
          // 重新绘制中心点
          this.centerLocation.longitude = coordinate[0]
          this.centerLocation.latitude = coordinate[1]
          this.setDotMarker()
        }
      })
    },
    /**
     * 给地图增加弹窗
     */
    addOverlay() {
      const elPopup = this.$refs.popup
      this.popup = new Overlay({
        element: elPopup,
        // 点相对于弹窗的位置
        positioning: 'top-left',
        stopEvent: false,
        offset: [5, 5]
      })
      this.mapObject.addOverlay(this.popup)
    },

    /**
       * 给地图增加弹窗
       */
    addActiveIconOverlay() {
      const elPopup = this.$refs.activeIcon
      this.activeIcon = new Overlay({
        element: elPopup,
        // 点相对于弹窗的位置
        positioning: 'center-center',
        stopEvent: false
      })
      this.mapObject.addOverlay(this.activeIcon)
    },

    /**
     * 打点
     */
    setDotMarker() {
      if (this.centerLayer) {
        this.mapObject.removeLayer(this.centerLayer)
      }
      const location = olProj.fromLonLat([this.centerLocation.longitude, this.centerLocation.latitude])
      var _featureList = []
      if (this.centerLocation) {
        const _style = new Style({
          image: new Icon({
            scale: 0.2,
            src: require('@/assets/map_icon/point.png')
          })
        })
        const _feature = new Feature({
          geometry: new Point(location)
        })
        _feature.setId('dot')
        _feature.setStyle(_style)
        _featureList.push(_feature)
        this.centerLayer = new VectorLayer({
          source: new VectorSource({
            features: _featureList
          })
        })
        this.mapObject.addLayer(this.centerLayer)
        this.setMapCenter(location)
      }
    },

    /**
     * 标记设备点
     */
    setDeviceMarker() {
      var _featureList = []
      if (this.deviceInfoList) {
        this.deviceInfoList.forEach(point => {
          const _style = new Style({
            image: new Icon({
              scale: 0.18,
              src: require('@/assets/map_icon/device.png')
            })
          })
          const _feature = new Feature({
            geometry: new Point(olProj.fromLonLat([point.longitude, point.latitude]))
          })
          // 用 feature的id来区分区站、设备
          _feature.setId('device-' + point.deviceId)
          _feature.setStyle(_style)
          _featureList.push(_feature)
        })
      }
      this.deviceLayer = new VectorLayer({
        source: new VectorSource({
          features: _featureList
        })
      })
      this.mapObject.addLayer(this.deviceLayer)
    },
    /**
     * 设置地图中心
     * @param location 经纬度
     */
    setMapCenter(location) {
      const view = this.mapObject.getView()
      view.setZoom(this.maxZoom) // 重新设置地图放大倍数
      view.setCenter(location) // 重新设置中心点的坐标
      this.mapObject.render()
    },

    /**
     * 回到默认地图中心
     */
    backMapCenter() {
      const view = this.mapObject.getView()
      view.setZoom(this.defaultZoom) // 重新设置地图放大倍数
      view.setCenter(olProj.fromLonLat(this.defaultCenter)) // 重新设置中心点的坐标
      this.mapObject.render()
      this.closePopup()
    },
    /**
     * 放大
     */
    zoomIn() {
      const view = this.mapObject.getView()
      const curZoom = view.getZoom()
      if (curZoom < this.maxZoom) {
        view.setZoom(curZoom + 1)
        this.mapObject.render()
      }
    },
    /**
     * 放小
     */
    zoomOut() {
      const view = this.mapObject.getView()
      const curZoom = view.getZoom()
      if (curZoom > this.minZoom) {
        view.setZoom(curZoom - 1)
        this.mapObject.render()
      }
    },
    /**
     * 设备定位
     */
    gotoDeviceLocation(item) {
      this.manualOpenPopup('device', item.deviceId)
    },
    /**
     * 区站定位
     */
    gotoSiteLocation(item) {
      this.manualOpenPopup('site', item.siteId)
    },
    /**
     * 手动触发弹窗
     * @param type 类型： site 区站 ， device 设备
     * @param featureId 元素id
     */
    manualOpenPopup(type, id) {
      console.log(this.selectedDevice)
      const featureId = type + '-' + id
      const layer = type === 'device' ? this.deviceLayer : this.siteLayer
      const vectorSource = layer.getSource()
      const feature = vectorSource.getFeatureById(featureId)
      console.log(feature)
      this.showPopup = false
      if (feature) {
        const coordinates = feature.getGeometry().getCoordinates()
        if (feature.getId().startsWith('device')) {
          this.popupType = 'device'
          // this.addSelectedDeviceMarker(coordinates)
        } else if (feature.getId().startsWith('site')) {
          // this.addSelectedSiteMarker(coordinates)
          this.popupType = 'site'
        }
        this.showPopup = true
        // 设置弹窗位置
        this.setMapCenter(coordinates)
        this.popup.setPosition(coordinates)
        this.activeIcon.setPosition(coordinates)
      }
    },
    /**
     * 选择设备打点
     * @param location 经纬度
     */
    addSelectedDeviceMarker(location) {
      if (this.selectedDeviceLayer) {
        this.mapObject.removeLayer(this.selectedDeviceLayer)
      }
      var _featureList = []
      if (location) {
        const _style = new Style({
          image: new Icon({
            scale: 0.25,
            src: require('@/assets/map_icon/device_active.png'),
            anchor: [0.48, 0.52]
          })
        })
        const _feature = new Feature({
          geometry: new Point(location)
        })
        _feature.setId('selectedDevice')
        _feature.setStyle(_style)
        _featureList.push(_feature)
        this.selectedDeviceLayer = new VectorLayer({
          source: new VectorSource({
            features: _featureList
          })
        })
        this.mapObject.addLayer(this.selectedDeviceLayer)
      }
    },
    /**
       * 选择区站打点
       * @param location 经纬度
       */
    addSelectedSiteMarker(location) {
      if (this.selectedSiteLayer) {
        this.mapObject.removeLayer(this.selectedSiteLayer)
      }
      var _featureList = []
      if (location) {
        const _style = new Style({
          image: new Icon({
            scale: 0.8,
            src: require('@/assets/map_icon/site_active.png'),
            anchor: [0.48, 0.52]
          })
        })
        const _feature = new Feature({
          geometry: new Point(location)
        })
        _feature.setId('selectedSite')
        _feature.setStyle(_style)
        _featureList.push(_feature)
        this.selectedSiteLayer = new VectorLayer({
          source: new VectorSource({
            features: _featureList
          })
        })
        this.mapObject.addLayer(this.selectedSiteLayer)
      }
    },

    /**
     * 标记区站点
     */
    addSiteMarker() {
      var _featureList = []
      if (this.siteList) {
        this.siteList.forEach(point => {
          const _style = new Style({
            image: new Icon({
              scale: 0.6,
              src: require('@/assets/map_icon/site.png')
            }),
            text: new Text({
              font: 'normal 13px 微软雅黑',
              // 对其方式
              textAlign: 'center',
              // 基准线
              textBaseline: 'middle',
              offsetY: -35,
              offsetX: 0,
              stroke: new Stroke({ color: '#409EFF', width: 10 }),
              // backgroundFill: new Stroke({
              //   color: '#fffff'
              // }),
              // 文本填充样式
              fill: new Fill({
                color: '#ffffff'
              }),
              // padding: [5, 5, 5, 5],
              text: `${point.siteName}`
            })
          })
          const _feature = new Feature({
            geometry: new Point(olProj.fromLonLat([point.longitude, point.latitude]))
          })
          // 用 feature的id来区分区站、设备
          _feature.setId('site-' + point.siteId)
          _feature.setStyle(_style)
          _featureList.push(_feature)
        })
      }
      this.siteLayer = new VectorLayer({
        source: new VectorSource({
          features: _featureList
        })
      })
      this.mapObject.addLayer(this.siteLayer)
    },

    /**
     * 关闭弹窗
     */
    closePopup() {
      this.showPopup = false
      this.selectedDevice = null
      this.selectedSite = null
      this.mapObject.removeLayer(this.centerLayer)
      this.mapObject.removeLayer(this.selectedDeviceLayer)
      this.mapObject.removeLayer(this.selectedSiteLayer)
    },

    /**
     * 获取设备信息
     */
    getAllDeviceInfo() {
      getAllDeviceInfo({}).then(res => {
        this.deviceInfoList = res.data
        this.setDeviceMarker()
      })
    },
    /**
     * checkList
     */
    showOption() {
      if (this.checkList.indexOf('区站') !== -1) {
        this.siteLayer.setVisible(true)
      } else {
        this.siteLayer.setVisible(false)
      }

      if (this.checkList.indexOf('设备') !== -1) {
        this.deviceLayer.setVisible(true)
      } else {
        this.deviceLayer.setVisible(false)
      }
    },

    /**
     * 跳转设备详情
     * @param e
     */
    gotoIntimeData() {
      const query = {
        deviceIdentification: this.selectedDevice.deviceIdentification,
        productIdentification: this.selectedDevice.productIdentification,
        deviceType: this.selectedDevice.deviceType
      }
      if (this.selectedDevice.deviceType === 'COMMON' && this.selectedDevice.model === 'ATMOSPHERE') {
        this.$router.push({ path: '/cms/device-data/meteorologicalMonitor', query: { 'row': JSON.stringify(query) }})
      } else if (this.selectedDevice.deviceType === 'COMMON' && this.selectedDevice.model === 'ICECOVER') {
        this.$router.push({ path: '/cms/device-data/iceCream', query: { 'row': JSON.stringify(query) }})
      } else if (this.selectedDevice.deviceType === 'COMMON' && this.selectedDevice.model === 'IMAGE') {
        this.$router.push({ path: '/cms/device-data/iceImages', query: { 'row': JSON.stringify(query) }})
      } else if (this.selectedDevice.deviceType === 'SUBSET' && this.selectedDevice.model === 'TEMP') {
        this.$router.push({ path: '/cms/device-data/temperature', query: { 'row': JSON.stringify(query) }})
      } else if (this.selectedDevice.deviceType === 'SUBSET' && this.selectedDevice.model === 'DPMT') {
        this.$router.push({ path: '/cms/device-data/displacement', query: { 'row': JSON.stringify(query) }})
      } else if (this.selectedDevice.deviceType === 'SUBSET' && this.selectedDevice.model === 'RANG') {
        this.$router.push({ path: '/cms/device-data/distance', query: { 'row': JSON.stringify(query) }})
      } else if (this.selectedDevice.deviceType === 'SUBSET' && this.selectedDevice.model === 'DPVN') {
        this.$router.push({ path: '/cms/device-data/inclinationVibration', query: { 'row': JSON.stringify(query) }})
      }
    },

    /**
     * 全屏控制
     */
    toggleFullScreen() {
      if (this.isFullScreen()) {
        this.exitFullScreen()
      } else {
        this.requestFullScreen(this.$refs.mapContainer)
      }
    },
    /**
     * 全屏
     */
    requestFullScreen(element) {
      if (element.requestFullscreen) {
        element.requestFullscreen()
      } else if (element.msRequestFullscreen) {
        element.msRequestFullscreen()
      } else if (element.mozRequestFullScreen) {
        element.mozRequestFullScreen()
      } else if (element.webkitRequestFullscreen) {
        element.webkitRequestFullscreen()
      }
    },
    /**
     * 退出全屏
     */
    exitFullScreen() {
      if (document.exitFullscreen) {
        document.exitFullscreen()
      } else if (document.msExitFullscreen) {
        document.msExitFullscreen()
      } else if (document.mozCancelFullScreen) {
        document.mozCancelFullScreen()
      } else if (document.webkitExitFullscreen) {
        document.webkitExitFullscreen()
      }
    },
    /**
     * 全屏判断
     */
    isFullScreen() {
      return (
        document.fullscreenElement ||
              document.msFullscreenElement ||
              document.mozFullScreenElement ||
              document.webkitFullscreenElement)
    }
  }
}
</script>

<style lang="scss" scoped>
  @keyframes ripple-effect {
    0% {
      transform: scale(1);
      opacity:1;
    }
    70% {
      transform: scale(1.2);
      opacity:0.8;
    }
    100% {
      transform: scale(1.6);
      opacity:0.2;
    }
  }
  .chart-map{
    width: 100%;
    height: 100%;
    position: relative;
  }
  .select-box{
    position: absolute;
    left: 15px;
    top: 15px;
    padding: 10px 5px;
    border-radius: 8px;
    background-color: white;
    box-shadow: 0 0 15px rgb(177, 177, 177);
    display: flex;
    flex-direction: row;
    width: 580px;
    justify-content: space-around;
    align-items: center;
    .select{
      width: 180px;
    }
    .checkBox{
      width: 140px;
      display: flex;
      flex-direction: row;
    }
  }
  .map-location{
    background-color: white;
    height: 32px;
    width: 32px;
    padding: 5px;
    position: absolute;
    border-radius: 8px;
    bottom: 15px;
    right: 15px;
    box-shadow: 0 0 15px rgb(177, 177, 177);
    .image{
      width: 22px;
      height: 22px;
    }
  }
  .map-full-screen{
    background-color: white;
    height: 32px;
    width: 32px;
    padding: 5px;
    position: absolute;
    border-radius: 8px;
    top: 15px;
    right: 15px;
    box-shadow: 0 0 15px rgb(177, 177, 177);
    .image{
      width: 22px;
      height: 22px;
    }
  }
  .map-zoom{
    background-color: white;
    width: 32px;
    height: 74px;
    display: flex;
    flex-direction: column;
    justify-content: space-around;
    padding: 5px;
    align-items: center;
    position: absolute;
    border-radius: 8px;
    bottom: 60px;
    right: 15px;
    box-shadow: 0 0 15px rgb(177, 177, 177);
    .line{
      width: 100%;
      height: 1px;
      background-color: #409EFF;
    }
    .image{
      width: 14px;
      height: 14px;
    }
  }
  .popup {
    width: 300px;
    background-color: white;
    box-shadow: 0 0 15px rgb(177, 177, 177);
    border-radius: 10px;
      .header-box{
        height: 36px;
        border-top-left-radius: 10px;
        border-top-right-radius: 10px;
        justify-content: center;
        align-items: center;
        font-size: 16px;
        font-weight: bold;
        color: white;
        display: flex;
        flex-direction: row;
        .close{
          position: absolute;
          top: 5px;
          right: 5px;
          width: 26px;
          height: 26px;
        }
        .network{
          position: absolute;
          top: 8px;
          left: 12px;
          width: 22px;
          height: 22px;
        }
      }
    .site-header{
      background-color: #409EFF;
    }
    .device-header{
      background-color: #13227A;
    }
    .content-box{
      padding: 10px;
      .text {
        font-size: 18px;
        padding-bottom: 10px;
      }
      .btn{
        background-color: #13227A;
        color: white;
        font-weight: bold;
      }
    }
  }
  .active-icon{
    width: 35px;
    height: 35px;
    .device-icon-box{
      width: 100%;
      height: 100%;
      position: relative;
      .icon{
        width: 35px;
        height: 35px;
        z-index: 2;
        position: absolute;
      }
      .ripple-icon{
        z-index: 1;
        position: absolute;
        width:100%;
        height:100%;
        border-radius:50%;
        background-color: #13227A; /* 或者你想要的任何颜色 */
        opacity:1;
        animation: ripple-effect 1s ease-out infinite;
      }
    }
    .site-icon-box{
      width: 100%;
      height: 100%;
      position: relative;
      .icon{
        width: 35px;
        height: 35px;
        z-index: 2;
        position: absolute;
      }
      .ripple-icon{
        z-index: 1;
        position: absolute;
        width:100%;
        height:100%;
        border-radius:50%;
        background-color: #409EFF; /* 或者你想要的任何颜色 */
        opacity:1;
        animation: ripple-effect 1s ease-out infinite;
      }
    }
  }
</style>
